package com.codeczx.customviewdemo.limitedscroller;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

import com.codeczx.customviewdemo.R;

/**
 * Created by codeczx on 2017/9/21.
 */

public class LimitedScroller extends LinearLayout {

    private static final int MSG_SET_DATA = 0;
    private static final int MSG_SCROLL = 1;
    private static final int PERIOD_TIME = 3000;
    private LinearLayout llNow;
    private LinearLayout llDown;
    private LimitedAdapter mAdapter;
    private int scrollHeight;
    // 标志是否已添加数据
    private boolean boundData = false;
    // 标志数据集的当前位置
    private int dataIndex = 0;
    // 每个容器里的限制个数
    private int limit = 2;
    private boolean isCancel;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_SET_DATA:
                    boundData(true);
                    break;
                case MSG_SCROLL:
                    startAnimation();
            }
        }
    };
    private long durationTime = 2000;

    public LimitedScroller(Context context) {
        this(context, null);
    }

    public LimitedScroller(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LimitedScroller(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.limited_scroller, this, true);
        llNow = (LinearLayout) view.findViewById(R.id.ll_now);
        llDown = (LinearLayout) view.findViewById(R.id.ll_down);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() / 2);
        scrollHeight = getMeasuredHeight();
    }

    public interface LimitedAdapter {
        int getCount();

        View getView(int index);
    }

    public void setAdapter(LimitedAdapter adapter) {
        mAdapter = adapter;
        mHandler.sendEmptyMessage(MSG_SET_DATA);
    }

    public void startScroll() {
        if (mAdapter == null || mAdapter.getCount() == 0) {
            return;
        }
        if (!boundData) {
            mHandler.sendEmptyMessage(MSG_SET_DATA);
        }
        isCancel = false;
        mHandler.removeMessages(MSG_SCROLL);
        mHandler.sendEmptyMessageDelayed(MSG_SCROLL, PERIOD_TIME);
    }

    public void boundData(boolean first) {
        if (mAdapter == null || mAdapter.getCount() == 0) {
            return;
        }
        if (first) {
            boundData = true;
            llNow.removeAllViews();
            for (int i = 0; i < limit; i++) {
                if (dataIndex > mAdapter.getCount() - 1) {
                    dataIndex = 0;
                }
                View view = mAdapter.getView(dataIndex);
                llNow.addView(view);
                dataIndex++;
            }
        }
        llDown.removeAllViews();
        for (int i = 0; i < limit; i++) {
            if (dataIndex > mAdapter.getCount() - 1) {
                dataIndex = 0;
            }
            View view = mAdapter.getView(dataIndex);
            llDown.addView(view);
            dataIndex++;
        }
    }

    public void startAnimation() {
        if (isCancel) {
            return;
        }
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(llNow, "Y", llNow.getY() - scrollHeight);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(llDown, "Y", llDown.getY() - scrollHeight);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(durationTime);
        animatorSet.playTogether(animator1, animator2);
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                llNow.setY(scrollHeight);
                llDown.setY(0);
                LinearLayout temp = llNow;
                llNow = llDown;
                llDown = temp;
                boundData(false);
                mHandler.removeMessages(MSG_SCROLL);
                mHandler.sendEmptyMessageDelayed(MSG_SCROLL, PERIOD_TIME);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animatorSet.start();
    }
}
